package scene;

import geometrie.Point;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Classe pour la Forme 3D d'un Cylindre
 * @author Manuel
 * @author Marcos
 *
 */
public class Cylindre implements Modele3D {
	/** Liste de facettes */
	private List<Facette3D> liste;
	/** Ensamble de points */
	private Point[] points;
	/** Point central du Cone */
	Point pCentral; 
	/** Radius */
	double radius; 
	/** Hauteur */
	double haut; 
	/** Nivel du Complexite */
	int n; 
	
	/**
	 * Constructeur pour generer le Cylindre
	 * @param pCentral Le point Centrale pour creer la circunference et la pointe
	 * @param radius Radius de la Circunference
	 * @param haut Hauteur de la pointe
	 * @param n Nivel du complexite
	 * @throws Exception "Erreur de Taille"
	 */
	public Cylindre(Point pCentral, double radius, double haut, int n) throws Exception{
		if(n>=3){
			liste = new ArrayList<Facette3D>();	
			this.pCentral = pCentral;
			this.n = n;
			this.radius = radius;
			this.haut = haut;
			creerCylindre();
		}
		else
			throw new Exception("Erreur de taille: il faut n >= 3");
	
	}
	/**
	 * Appeler des methodes pour generer le Cylindre
	 */
	private void creerCylindre(){	
		genererPoints();
		Facette3D[] f = creerFacettes();
		for(int i = 0 ; i < n*4 ; i++)
			liste.add(f[i]);
	}
	/**
	 * Generer le tableau des points
	 */
	private void genererPoints(){
		double angle = 0;
		points= new Point[n*2];
		//points[0] = new Point(pCentral.getXCartesien(),pCentral.getYCartesien(),pCentral.getZCartesien() + haut );
		for(int i = 0; i < n; i++){
			double x = pCentral.getXCartesien() + radius * Math.cos(Math.toRadians(angle));
			double y = pCentral.getYCartesien() + radius * Math.sin(Math.toRadians(angle));
			
			points[i] = new Point(Math.round(x),Math.round(y), pCentral.getZCartesien());
			points[i+n] = new Point(Math.round(x),Math.round(y), pCentral.getZCartesien()+haut);
			
			//p[i+n/2] = new Point(pCentral.getXCartesien() + (-1) * radius * Math.cos(angle),pCentral.getYCartesien() + (-1) *  radius * Math.sin(angle), pCentral.getZCartesien());
			System.out.println("P["+i+"]: " + points[i] + ", Angle: " + angle);
			System.out.println("P["+(i+n)+"]: " + points[n+i] + ", Angle: " + angle);
			angle = angle + getAngle();			
		}		
	}
	/**
	 * Deplacer le Cylindre dans le Space
	 * @param x Valeur a deplacer dans X
	 * @param y Valeur a deplacer dans Y
	 * @param z Valeur a deplacer dans Z
	 */
	public void deplacer(double x, double y, double z){
		//deplacer le point central
		pCentral.set(x+pCentral.getXCartesien(),y+ pCentral.getYCartesien(),z+pCentral.getZCartesien());
		//Le reste des points dans la liste
		for(int i = 0;i<points.length;i++)
			points[i].set(x+points[i].getXCartesien(),y+ points[i].getYCartesien(),z+points[i].getZCartesien());
		Facette3D[] f = creerFacettes();
		liste.clear();
		for(int i = 0 ; i < n*4 ; i++)
			liste.add(f[i]);		
	}
	/**
	 * Creer des facettes a partir du tableau des points.
	 * On commence avec le point au dessus et leur connecte
	 * avec des points a la circunference
	 * @return tableau de facettes
	 */
	private Facette3D[] creerFacettes(){

		Facette3D[] f = new Facette3D[n*4];
		//Remplir des circunferences
		for(int i = 0; i < n;i++){
			//Couverture
			f[i] = new Facette3D(pCentral,points[(i)],points[(i+1)%n]);
			//Creer le point centrale au-dessus
			Point p = new Point(pCentral.getXCartesien(), pCentral.getYCartesien(),pCentral.getZCartesien() + haut);
			f[i+n] = new Facette3D(p,points[i+n],points[(i+1)%(n)+n]);
			
			//Cotes
			f[i+n*2] = new Facette3D(points[i],points[(i+1)%n],points[(i+1)%n+n]); //bien!
			f[i+n*3] = new Facette3D(points[(i)%n],points[(i+1)%n+n],points[i+n]);
		}
		return f;		
	}
	/**
	 * Obtenir la liste du Objet
	 * @return
	 */
	public List<Facette3D> getListe(){
		return liste;
	}
	/**
	 * Obtenir le angle avec la complexite du Cone.
	 * @return angle = 360 / nivel de complexite
	 */
	private double getAngle(){
		return 360 / (new Integer(n).doubleValue());
	}
	/**
	 * Obtenir l'Iterator de la liste de Facettes 3D
	 */
	@Override
	public Iterator<Facette3D> getFacettes() {
		// TODO Auto-generated method stub
		return liste.iterator();
	}
	/**
	 * Boucher le Trou (il n'y aucun)
	 */
	@Override
	public void triangulePolygone(Point[] polygone) {
		// TODO Auto-generated method stub
		
	}

}
